package org.example.demo.service;

import java.lang.Exception;
import java.lang.String;
import java.util.Arrays;
import javax.annotation.PostConstruct;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.example.demo.model.bo.EducationCertificationCertificatesInputBO;
import org.example.demo.model.bo.EducationCertificationCreateStudentRecordInputBO;
import org.example.demo.model.bo.EducationCertificationGetCertificateInputBO;
import org.example.demo.model.bo.EducationCertificationGetStudentRecordInputBO;
import org.example.demo.model.bo.EducationCertificationIssueCertificateInputBO;
import org.example.demo.model.bo.EducationCertificationRevokeCertificateInputBO;
import org.example.demo.model.bo.EducationCertificationStudentsInputBO;
import org.example.demo.model.bo.EducationCertificationUpdateCertificateInputBO;
import org.example.demo.model.bo.EducationCertificationVerifyCertificateInputBO;
import org.fisco.bcos.sdk.client.Client;
import org.fisco.bcos.sdk.transaction.manager.AssembleTransactionProcessor;
import org.fisco.bcos.sdk.transaction.manager.TransactionProcessorFactory;
import org.fisco.bcos.sdk.transaction.model.dto.CallResponse;
import org.fisco.bcos.sdk.transaction.model.dto.TransactionResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
@NoArgsConstructor
@Data
public class EducationCertificationService {
  public static final String ABI = org.example.demo.utils.IOUtil.readResourceAsString("abi/EducationCertification.abi");

  public static final String BINARY = org.example.demo.utils.IOUtil.readResourceAsString("bin/ecc/EducationCertification.bin");

  public static final String SM_BINARY = org.example.demo.utils.IOUtil.readResourceAsString("bin/sm/EducationCertification.bin");

  @Value("${system.contract.educationCertificationAddress}")
  private String address;

  @Autowired
  private Client client;

  AssembleTransactionProcessor txProcessor;

  @PostConstruct
  public void init() throws Exception {
    this.txProcessor = TransactionProcessorFactory.createAssembleTransactionProcessor(this.client, this.client.getCryptoSuite().getCryptoKeyPair());
  }

  public CallResponse getCertificate(EducationCertificationGetCertificateInputBO input) throws Exception {
    return this.txProcessor.sendCall(this.client.getCryptoSuite().getCryptoKeyPair().getAddress(), this.address, ABI, "getCertificate", input.toArgs());
  }

  public CallResponse verifyCertificate(EducationCertificationVerifyCertificateInputBO input) throws Exception {
    if (input == null) {
      throw new IllegalArgumentException("input参数不能为空");
    }
    
    if (input.get_certificateId() == null) {
      throw new IllegalArgumentException("证书ID不能为空");
    }
    
    if (input.get_hash() == null || input.get_hash().length == 0) {
      throw new IllegalArgumentException("证书哈希不能为空");
    }
    
    System.out.println("EducationCertificationService.verifyCertificate - 开始执行");
    System.out.println("验证证书ID: " + input.get_certificateId());
    System.out.println("验证证书哈希: " + org.fisco.bcos.sdk.utils.Numeric.toHexString(input.get_hash()));
    System.out.println("合约地址: " + this.address);
    System.out.println("ABI: " + (ABI != null ? "已加载" : "未加载"));
    System.out.println("参数列表: " + input.toArgs());
    
    try {
      // 显式创建函数对象
      org.fisco.bcos.sdk.abi.datatypes.Function function = 
        new org.fisco.bcos.sdk.abi.datatypes.Function(
          "verifyCertificate",
          java.util.Arrays.asList(
            new org.fisco.bcos.sdk.abi.datatypes.generated.Uint256(input.get_certificateId()),
            new org.fisco.bcos.sdk.abi.datatypes.generated.Bytes32(input.get_hash())
          ),
          java.util.Arrays.asList(new org.fisco.bcos.sdk.abi.TypeReference<org.fisco.bcos.sdk.abi.datatypes.Bool>() {})
        );
      
      System.out.println("创建函数对象: " + function.toString());
      System.out.println("函数名称: " + function.getName());
      System.out.println("函数参数: " + function.getInputParameters());
      
      // 准备调用
      System.out.println("准备执行调用...");
      CallResponse response = this.txProcessor.sendCall(
        this.client.getCryptoSuite().getCryptoKeyPair().getAddress(), 
        this.address, 
        ABI, 
        "verifyCertificate", 
        input.toArgs()
      );
      
      if (response == null) {
        System.err.println("调用响应为空");
        throw new RuntimeException("调用响应为空");
      }
      
      if (response.getValues() == null) {
        System.err.println("调用结果为空");
        throw new RuntimeException("调用结果为空");
      }
      
      System.out.println("调用执行成功");
      System.out.println("调用结果: " + response.getValues());
      
      return response;
    } catch (Exception e) {
      System.err.println("验证证书调用执行异常: " + e.getMessage());
      e.printStackTrace();
      throw e;
    }
  }

  public TransactionResponse createStudentRecord(EducationCertificationCreateStudentRecordInputBO input) throws Exception {
    return this.txProcessor.sendTransactionAndGetResponse(this.address, ABI, "createStudentRecord", input.toArgs());
  }

  public CallResponse certificates(EducationCertificationCertificatesInputBO input) throws Exception {
    return this.txProcessor.sendCall(this.client.getCryptoSuite().getCryptoKeyPair().getAddress(), this.address, ABI, "certificates", input.toArgs());
  }

  public CallResponse students(EducationCertificationStudentsInputBO input) throws Exception {
    return this.txProcessor.sendCall(this.client.getCryptoSuite().getCryptoKeyPair().getAddress(), this.address, ABI, "students", input.toArgs());
  }

  public CallResponse nextCertificateId() throws Exception {
    return this.txProcessor.sendCall(this.client.getCryptoSuite().getCryptoKeyPair().getAddress(), this.address, ABI, "nextCertificateId", Arrays.asList());
  }

  public TransactionResponse issueCertificate(EducationCertificationIssueCertificateInputBO input) throws Exception {
    if (input == null) {
      throw new IllegalArgumentException("input参数不能为空");
    }
    
    if (input.get_studentId() == null || input.get_studentId().isEmpty()) {
      throw new IllegalArgumentException("学生ID不能为空");
    }
    
    if (input.get_certificateType() == null || input.get_certificateType().isEmpty()) {
      throw new IllegalArgumentException("证书类型不能为空");
    }
    
    if (input.get_certificateNumber() == null || input.get_certificateNumber().isEmpty()) {
      throw new IllegalArgumentException("证书编号不能为空");
    }
    
    if (input.get_issueDate() == null || input.get_issueDate().isEmpty()) {
      throw new IllegalArgumentException("颁发日期不能为空");
    }
    
    if (input.get_institution() == null || input.get_institution().isEmpty()) {
      throw new IllegalArgumentException("机构名称不能为空");
    }
    
    if (input.get_hash() == null || input.get_hash().length == 0) {
      throw new IllegalArgumentException("证书哈希不能为空");
    }
    
    System.out.println("EducationCertificationService.issueCertificate - 参数校验通过");
    System.out.println("合约地址: " + this.address);
    System.out.println("ABI: " + (ABI != null ? "已加载" : "未加载"));
    System.out.println("输入参数: " + input);
    System.out.println("参数列表: " + input.toArgs());
    
    try {
      TransactionResponse response = this.txProcessor.sendTransactionAndGetResponse(this.address, ABI, "issueCertificate", input.toArgs());
      
      if (response == null) {
        System.err.println("交易响应为空");
        throw new RuntimeException("交易响应为空");
      }
      
      if (response.getTransactionReceipt() == null) {
        System.err.println("交易回执为空");
        throw new RuntimeException("交易回执为空");
      }
      
      return response;
    } catch (Exception e) {
      System.err.println("发送交易异常: " + e.getMessage());
      e.printStackTrace();
      throw e;
    }
  }

  public CallResponse admin() throws Exception {
    return this.txProcessor.sendCall(this.client.getCryptoSuite().getCryptoKeyPair().getAddress(), this.address, ABI, "admin", Arrays.asList());
  }

  public CallResponse getStudentRecord(EducationCertificationGetStudentRecordInputBO input) throws Exception {
    return this.txProcessor.sendCall(this.client.getCryptoSuite().getCryptoKeyPair().getAddress(), this.address, ABI, "getStudentRecord", input.toArgs());
  }

  public TransactionResponse revokeCertificate(EducationCertificationRevokeCertificateInputBO input) throws Exception {
    if (input == null) {
      throw new IllegalArgumentException("input参数不能为空");
    }

    if (input.get_certificateId() == null) {
      throw new IllegalArgumentException("证书ID不能为空");
    }

    System.out.println("EducationCertificationService.revokeCertificate - 开始执行");
    System.out.println("撤销证书ID: " + input.get_certificateId());
    System.out.println("合约地址: " + this.address);
    System.out.println("ABI: " + (ABI != null ? "已加载" : "未加载"));
    System.out.println("参数列表: " + input.toArgs());

    try {
      // 显式创建函数对象
      org.fisco.bcos.sdk.abi.datatypes.Function function = 
        new org.fisco.bcos.sdk.abi.datatypes.Function(
          "revokeCertificate",
          java.util.Arrays.asList(
            new org.fisco.bcos.sdk.abi.datatypes.generated.Uint256(input.get_certificateId())
          ),
          java.util.Collections.emptyList()
        );

      System.out.println("创建函数对象: " + function.toString());
      System.out.println("函数名称: " + function.getName());
      System.out.println("函数参数: " + function.getInputParameters());

      // 准备交易处理
      System.out.println("准备执行交易...");
      TransactionResponse response = this.txProcessor.sendTransactionAndGetResponse(
        this.address, ABI, "revokeCertificate", input.toArgs());

      if (response == null) {
        System.err.println("交易响应为空");
        throw new RuntimeException("交易响应为空");
      }

      if (response.getTransactionReceipt() == null) {
        System.err.println("交易回执为空");
        throw new RuntimeException("交易回执为空");
      }

      System.out.println("交易执行成功");
      System.out.println("交易哈希: " + response.getTransactionReceipt().getTransactionHash());
      System.out.println("区块号: " + response.getTransactionReceipt().getBlockNumber());
      System.out.println("交易状态: " + response.getTransactionReceipt().getStatus());

      return response;
    } catch (Exception e) {
      System.err.println("撤销证书交易执行异常: " + e.getMessage());
      e.printStackTrace();
      throw e;
    }
  }

  public TransactionResponse updateCertificate(EducationCertificationUpdateCertificateInputBO input) throws Exception {
    if (input == null) {
      throw new IllegalArgumentException("input参数不能为空");
    }
    
    if (input.get_certificateId() == null) {
      throw new IllegalArgumentException("证书ID不能为空");
    }
    
    if (input.get_certificateType() == null || input.get_certificateType().isEmpty()) {
      throw new IllegalArgumentException("证书类型不能为空");
    }
    
    if (input.get_certificateNumber() == null || input.get_certificateNumber().isEmpty()) {
      throw new IllegalArgumentException("证书编号不能为空");
    }
    
    if (input.get_issueDate() == null || input.get_issueDate().isEmpty()) {
      throw new IllegalArgumentException("颁发日期不能为空");
    }
    
    if (input.get_institution() == null || input.get_institution().isEmpty()) {
      throw new IllegalArgumentException("机构名称不能为空");
    }
    
    if (input.get_hash() == null || input.get_hash().length == 0) {
      throw new IllegalArgumentException("证书哈希不能为空");
    }
    
    if (input.get_isValid() == null) {
      throw new IllegalArgumentException("证书有效性状态不能为空");
    }
    
    System.out.println("EducationCertificationService.updateCertificate - 参数校验通过");
    System.out.println("合约地址: " + this.address);
    System.out.println("输入参数: " + input);
    System.out.println("参数列表: " + input.toArgs());
    
    try {
      TransactionResponse response = this.txProcessor.sendTransactionAndGetResponse(this.address, ABI, "updateCertificate", input.toArgs());
      
      if (response == null) {
        System.err.println("交易响应为空");
        throw new RuntimeException("交易响应为空");
      }
      
      if (response.getTransactionReceipt() == null) {
        System.err.println("交易回执为空");
        throw new RuntimeException("交易回执为空");
      }
      
      return response;
    } catch (Exception e) {
      System.err.println("发送交易异常: " + e.getMessage());
      e.printStackTrace();
      throw e;
    }
  }
}
